package com.xayy.health.ds.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import cn.kawins.base.result.CheckResult;
import cn.kawins.base.utils.CollUtil;
import cn.kawins.base.utils.HttpUtil;
import cn.kawins.base.utils.StringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xayy.health.core.constant.TableNameConstant;
import com.xayy.health.core.enums.ModelTrainStatusEnum;
import com.xayy.health.core.enums.ModuleEnum;
import com.xayy.health.core.enums.SystemModelTypeEnum;
import com.xayy.health.core.exception.HealthException;
import com.xayy.health.ds.model.*;
import com.xayy.health.ds.service.*;
import com.xayy.health.mgt.model.CalculateData;
import com.xayy.health.mgt.model.CalculateUpdateModelParam;
import com.xayy.health.mgt.model.dto.TelemetryDto;
import com.xayy.health.mgt.model.vo.PredictDataVo;
import com.xayy.health.mgt.model.vo.ResultDataVo;
import com.xayy.health.mgt.model.vo.TaskResultVo;
import com.xayy.health.mgt.service.FaultReportService;
import com.xtck.ha.common.core.web.service.dsimpl.BaseServiceImpl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Description: DsAlgorithmParamsService实现类
 * @Auther:liuyuan
 * @Date:2025-07-08
 */
@Slf4j
@Service
public class DsCalculateServiceImpl extends BaseServiceImpl<DsAlgorithmParams> implements DsCalculateService {
    @Autowired
    DsModelTrainRecordService dsModelTrainRecordService;
    @Autowired
    DsDiagnoseService dsDiagnoseService;
    @Autowired
    DsHealthAlgorithmManageService dsHealthAlgorithmManageService;
    @Autowired
    FaultReportService faultReportService;
    @Autowired
    DsModelTrainAccuracyService dsModelTrainAccuracyService;
    @Autowired
    DsModelAlgorithmInfoService dsModelAlgorithmInfoService;
    @Autowired
    DsSelectTelemetryDataService dsSelectTelemetryDataService;
    @Autowired
    DsTaskInfoService dsTaskInfoService;
    @Autowired
    DsFaultInfoService dsFaultInfoService;

    /**
     * 模型训练
     *
     * @param modelTrain
     * @return CheckResult<Object>
     * @Param recordId 记录id
     */
    // @Async
    @Override
    public CheckResult<Object> modelTrial(DsCalculateModelTrain modelTrain, Long recordId) throws UnknownHostException {
        List<DsAlgorithmParams> algorithmParamList = modelTrain.getAlgorithmParamList();
        if (CollUtil.isEmpty(algorithmParamList) || algorithmParamList.size() != 9)
            return CheckResult.fail("模型参数不能不空");
        List<DsModelAlgorithmInfo> modelAlgorithmInfos = this.assembleAlgorithmParamList(modelTrain, recordId, algorithmParamList);
        //旧模型设置模型名称
        if(StrUtil.isNotEmpty(modelTrain.getOldModelName())){
            DsModelTrainRecord modelTrainRecord = new DsModelTrainRecord();
            List<DsModelTrainRecord> recordList = dsModelTrainRecordService.selectTList(DsModelTrainRecord.builder().id(modelTrain.getOldModelName()).build());
            if (null!=recordList && recordList.size()>0)
                modelTrainRecord = recordList.get(0);
            modelTrain.setModelName(modelTrainRecord.getModelName());
        }
        //判断遥测数据中是否含有空值
        String[] paramCodes =new String[]{modelTrain.getParamCode()};
        TelemetryDto telemetryDto = new TelemetryDto().setSatelliteCode(modelTrain.getSatelliteCode()).setStartTime(modelTrain.getStartTime()).setEndTime(modelTrain.getEndTime()).setParamCodes(paramCodes);
        Map<String, List<DsTelemetryData>> listMap = dsDiagnoseService.selectTelemetryData(telemetryDto);
        //判断是否存在空值
        for (Map.Entry<String, List<DsTelemetryData>> map : listMap.entrySet()) {
            List<DsTelemetryData> list = map.getValue();
            if (!CollectionUtils.isEmpty(list)) {
                for (DsTelemetryData data : list) {
                    if (StringUtils.isEmpty(data.getValue())) {
                        throw new HealthException("参数 " + map.getKey() + " 存在空值.......");
                    }
                }
            }
        }
        /**查询算法信息*/
        List<DsHealthAlgorithmManage> dsHealthAlgorithmManageList = dsHealthAlgorithmManageService.selectTList(DsHealthAlgorithmManage.builder()
                        .algorithmName(modelTrain.getAlgorithmName())
                        .build());
        DsHealthAlgorithmManage algorithm = new DsHealthAlgorithmManage();
        if (!CollectionUtils.isEmpty(dsHealthAlgorithmManageList))
            algorithm = dsHealthAlgorithmManageList.get(0);
        HttpResponse postResponse;
        try {
            postResponse = HttpUtil.createRequest(Method.POST, algorithm.getTrialAddr()).body(JSON.toJSONString(modelTrain)).execute();
        } catch (Exception e) {
            faultReportService.faultReport(ModuleEnum.SHZD.getCode(), ModuleEnum.SHZD.getMsg(),"调用接口失败","调用接口失败");
            return CheckResult.fail("调用接口失败：" + e.getMessage());
        }
        if (postResponse.getStatus() != 200) {
            try {
                // 修改训练记录状态
                DsModelTrainRecord modelTrainRecord = DsModelTrainRecord.builder().id(recordId.toString())
                        .status(ModelTrainStatusEnum.ABNORMAL.getCode()).build();
                modelTrainRecord = dsModelTrainRecordService.selectTList(modelTrainRecord).get(0);
                modelTrainRecord.setStatus(ModelTrainStatusEnum.ABNORMAL.getCode());
                dsModelTrainRecordService.updateT(modelTrainRecord);
                Map map = JSONObject.parseObject(postResponse.body(), Map.class);
                if (StrUtil.isEmpty(modelTrain.getOldModelName()))
                    dsModelTrainRecordService.deleteTList(DsModelTrainRecord.builder().modelName(modelTrain.getModelName()).build());
                log.error("调用模型训练算法结果异常");
                return CheckResult.fail(map.get("msg").toString());
            } catch (Exception e) {
                faultReportService.faultReport(ModuleEnum.SHZD.getCode(), ModuleEnum.SHZD.getMsg(),"模型训练数据出错","调用算法失败");
                return CheckResult.fail("调用算法失败，http状态码：" + postResponse.getStatus());
            }
        }
        JSONObject result = JSON.parseObject(postResponse.body());
        if (!result.getInteger("code").equals(200)) {
            dsModelTrainRecordService.updateT(DsModelTrainRecord.builder().id(recordId.toString()).status(ModelTrainStatusEnum.ABNORMAL.getCode()).build());
            return CheckResult.fail(result.getString("msg"));
        }
        // 修改训练记录状态
        Map<String, Object> data = result.getObject("data", Map.class);
        // BigDecimal acc = (BigDecimal) data.get("acc");
        BigDecimal acc = new BigDecimal(1);
        Object offset = data.get("offset");
        Integer status = (Integer) data.get("status");
        List<Map<String, String>> test_model = (List<Map<String, String>>) data.get("test_model");
        // 旧模型操作
        if (StrUtil.isNotEmpty(modelTrain.getOldModelName())) {
            DsModelTrainRecord trainRecord = BeanUtil.copyProperties(modelTrain, DsModelTrainRecord.class);
            DsModelTrainRecord oldModelTrainRecord = dsModelTrainRecordService.selectTById(modelTrain.getOldModelName());
            trainRecord.setModelName(oldModelTrainRecord.getModelName());
            trainRecord.setId(modelTrain.getOldModelName());
            trainRecord.setOffset(offset.toString());
            trainRecord.setStatus(ModelTrainStatusEnum.DONE.getCode());
            trainRecord.setAccuracy(acc.toString());
            dsModelTrainRecordService.updateT(trainRecord);
            dsModelTrainAccuracyService
                    .deleteTList(DsModelTrainAccuracy.builder().modelTrainRecordId(oldModelTrainRecord.getId()).build());
            // 插入修改后的模型数据
            updateModelTrainData(test_model, modelTrain, oldModelTrainRecord.getId(), null);
            updateAlgorithmInfo(true, oldModelTrainRecord.getId(), modelAlgorithmInfos);
        } else {
            DsModelTrainRecord modelTrainRecord =
                    DsModelTrainRecord.builder().id(recordId.toString()).offset(offset.toString())
                            .status(ModelTrainStatusEnum.DONE.getCode()).accuracy(acc.toString()).build();
            dsModelTrainRecordService.updateT(modelTrainRecord);
            updateAlgorithmInfo(false, recordId.toString(), modelAlgorithmInfos);
            if (CollUtil.isNotEmpty(test_model))
                updateModelTrainData(test_model, modelTrain, null, recordId);
        }
        List<DsTelemetryData> list = listMap.get(modelTrain.getParamCode());
        log.info("训练完数据格式化为.....list={}",list.get(0));
        if(!CollectionUtils.isEmpty(list)){
            String tableName = TableNameConstant.MODEL_TRAIN_TELEMETRY + recordId;
            dsSelectTelemetryDataService.createTaskTable(tableName);
            dsSelectTelemetryDataService.deleteTelemetryData(tableName);
            dsSelectTelemetryDataService.insertTelemetryListData(tableName, list);
        }
        HashMap<String, Object> testModel = new HashMap<>();
//        if(!CollectionUtils.isEmpty(test_model)){
//            test_model=DiagnoseServiceImpl.addDataToListForTrain(test_model);
//        }
        testModel.put("testModel", test_model);
        return CheckResult.success(testModel);
    }

    /**
     * 更新算法信息
     *
     * @param isUpdate            是否是旧模型
     * @param modelId             模型id
     * @param modelAlgorithmInfos 模型信息
     */
    private void updateAlgorithmInfo(Boolean isUpdate, String modelId, List<DsModelAlgorithmInfo> modelAlgorithmInfos) {
        if (Boolean.TRUE.equals(isUpdate)) {
            dsModelAlgorithmInfoService.deleteTList(DsModelAlgorithmInfo.builder().modelId(modelId).build());
        }
        for (DsModelAlgorithmInfo info:modelAlgorithmInfos){
            dsModelAlgorithmInfoService.insertT(info);
        }
    }

    /**
     * 修改模型数据
     *
     * @param test_model
     * @param modelTrain
     * @param oldmodelTrainId 判断是否是旧模型
     */
    public void updateModelTrainData(List<Map<String, String>> test_model, DsCalculateModelTrain modelTrain,
                                     String oldmodelTrainId, Long recordId) {
        ArrayList<DsModelTrainAccuracy> telemetryList = new ArrayList<>();
        for (Map<String, String> model : test_model) {
            String time = model.get("time");
            String value = Convert.toStr(model.get("value"));
            DsModelTrainAccuracy modelTrainAccuracy = DsModelTrainAccuracy.builder().time(time).value(value).valueType("1")
                    .sateCode(modelTrain.getSatelliteCode()).paramCode(modelTrain.getParamCode()).build();
            if (StringUtil.isEmpty(oldmodelTrainId)) {
                modelTrainAccuracy.setModelTrainRecordId(recordId.toString());
            } else {
                modelTrainAccuracy.setModelTrainRecordId(oldmodelTrainId);
            }
            telemetryList.add(modelTrainAccuracy);
        }
        for (DsModelTrainAccuracy body : telemetryList){
            dsModelTrainAccuracyService.insertT(body);
        }
    }

    /**
     * 组装模型参数列表数据
     *
     * @param modelTrain
     * @return
     */
    public List<DsModelAlgorithmInfo> assembleAlgorithmParamList(DsCalculateModelTrain modelTrain, Long recordId, List<DsAlgorithmParams> algorithmParamList) {
        algorithmParamList.sort(Comparator.comparing(DsAlgorithmParams::getId));
        CalculateUpdateModelParam calculateUpdateModelParam = new CalculateUpdateModelParam();
        calculateUpdateModelParam.setFilters(algorithmParamList.get(0).getParamValueEnd());
        calculateUpdateModelParam.setActivation(algorithmParamList.get(1).getParamValueEnd());
        calculateUpdateModelParam.setUnits(algorithmParamList.get(2).getParamValueEnd());
        calculateUpdateModelParam.setLstmActivation(algorithmParamList.get(3).getParamValueEnd());
        calculateUpdateModelParam.setDenseActivation(algorithmParamList.get(4).getParamValueEnd());
        calculateUpdateModelParam.setLossMetric(algorithmParamList.get(5).getParamValueEnd());
        calculateUpdateModelParam.setOptimizer(algorithmParamList.get(6).getParamValueEnd());
        calculateUpdateModelParam.setEpochs(algorithmParamList.get(7).getParamValueEnd());
        calculateUpdateModelParam.setBatchSize(algorithmParamList.get(8).getParamValueEnd());
        modelTrain.setCalculateUpdateModelParam(calculateUpdateModelParam);
        List<DsModelAlgorithmInfo> modelAlgorithmInfos = new ArrayList<>(algorithmParamList.size());
        algorithmParamList.forEach(x -> {
            DsModelAlgorithmInfo modelAlgorithmInfo = cn.kawins.base.utils.BeanUtil.copyBean(x, DsModelAlgorithmInfo.class);
            modelAlgorithmInfo.setModelId(recordId.toString());
            if (StrUtil.isNotEmpty(modelTrain.getOldModelName()))
                modelAlgorithmInfo.setModelId(modelTrain.getOldModelName());
            modelAlgorithmInfo.setId(null);
            modelAlgorithmInfos.add(modelAlgorithmInfo);
        });
        return modelAlgorithmInfos;
    }

    /**
     * 调用模型
     *
     * @param modelTrain
     */
    @Override
    public CheckResult<?> startModel(DsCalculateModelTrain modelTrain) {
        return calculate(modelTrain);
    }

    /**
     * 模型
     *
     * @param modelTrain
     * @return
     */
    @SneakyThrows
    private CheckResult<?> calculate(DsCalculateModelTrain modelTrain) {
        String[] paramCodes =new String[]{modelTrain.getParamCode()};
        TelemetryDto telemetry = new TelemetryDto().setSatelliteCode(modelTrain.getSatelliteCode()).setStartTime(modelTrain.getStartTime()).setEndTime(modelTrain.getEndTime()).setParamCodes(paramCodes);
        Map<String, List<DsTelemetryData>> listMap = dsDiagnoseService.selectTelemetryData(telemetry);
        //判断是否存在空值
        for (Map.Entry<String, List<DsTelemetryData>> map : listMap.entrySet()) {
            List<DsTelemetryData> list = map.getValue();
            if (!CollectionUtils.isEmpty(list)) {
                for (DsTelemetryData data : list) {
                    if (StringUtils.isEmpty(data.getValue())) {
                        throw new HealthException("参数 " + map.getKey() + " 存在空值.......");
                    }
                }
            }
        }
        List<DsHealthAlgorithmManage> healthAlgorithmManageList = dsHealthAlgorithmManageService.selectTList(DsHealthAlgorithmManage.builder().algorithmName(modelTrain.getAlgorithmName()).build());
        DsHealthAlgorithmManage algorithm = new DsHealthAlgorithmManage();
        if (null != healthAlgorithmManageList && healthAlgorithmManageList.size()>0 ){
            algorithm = healthAlgorithmManageList.get(0);
        }
        String url = algorithm.getPredictAddr();
        HttpResponse postResponse;
        try {
            postResponse = HttpUtil.createRequest(Method.POST, url).body(JSON.toJSONString(modelTrain)).execute();
        } catch (Exception e) {
            faultReportService.faultReport(ModuleEnum.SHZD.getCode(), ModuleEnum.SHZD.getMsg(),"调用接口失败","调用接口失败");
            return CheckResult.fail("调用接口失败：" + e.getMessage());
        }
        if (postResponse.getStatus() != 200) {
            try {
                Map map = JSONObject.parseObject(postResponse.body(), Map.class);
                log.error("调用模型算法结果异常");
                return CheckResult.fail(map.get("msg").toString());
            } catch (Exception e) {
                faultReportService.faultReport(ModuleEnum.SHZD.getCode(), ModuleEnum.SHZD.getMsg(),"调用算法失败","调用算法异常");
                return CheckResult.fail("调用算法失败，http状态码：" + postResponse.getStatus());
            }
        }
        JSONObject result = JSON.parseObject(postResponse.body());
        if (!result.getInteger("code").equals(200)) {
            return CheckResult.fail(result.getString("msg"));
        }
        Map<String, Object> data = result.getObject("data", Map.class);
        List<Map<String, String>> originalData = (List<Map<String, String>>) data.get("original");
        List<Map<String, String>> calculateResult = (List<Map<String, String>>) data.get("result");
        Map<String, String> map = originalData.get(originalData.size() - 1);
        long startLongTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(map.get("time")).getTime();
        long endTime = startLongTime + ((long) modelTrain.getPredNumber() * modelTrain.getTimeSpan() * 1000);
        TelemetryDto telemetryDto = new TelemetryDto();
        telemetryDto.setSatelliteCode(modelTrain.getSatelliteCode());
        telemetryDto.setParamCode(modelTrain.getParamCode());
        telemetryDto.setParamCodes(new String[]{modelTrain.getParamCode()});
        telemetryDto.setStartTime(new Date(startLongTime));
        telemetryDto.setEndTime(new Date(endTime));
        Map<String, List<DsTelemetryData>> map1 = dsDiagnoseService.selectTelemetryData(telemetryDto);
        List<DsTelemetryData> ycListData = map1.get(modelTrain.getParamCode());
        if (CollUtil.isNotEmpty(ycListData)) {
            //ycListData=addTelemetryDataToList(ycListData);
            ycListData=ycListData.stream().sorted(Comparator.comparing(DsTelemetryData::getTime)).collect(Collectors.toList());
            //originalData=addTelemetryDataToMap(originalData);
            data.put("OriginalForecastCurve", ycListData);
            data.put("original", originalData);
        } else {
            data.put("OriginalForecastCurve", new ArrayList<Map<String, String>>());
        }
        List<String> timeList = getTimeList(originalData, calculateResult, ycListData);
        data.put("xData", timeList);
        data.put("threshold",modelTrain.getThreshold());
        return CheckResult.success(data);
    }

    /**
     * 重组预测时间列表
     *
     * @param originalData    原始数据
     * @param calculateResult 预测数据
     * @param ycListData      遥测数据
     * @return
     */
    private List<String> getTimeList(List<Map<String, String>> originalData, List<Map<String, String>> calculateResult,
                                     List<DsTelemetryData> ycListData) {
        List<String> times = new ArrayList<>();
        originalData.forEach(x -> {
            times.add(x.get("time"));
        });
        ycListData.forEach(x -> {
            times.add(x.getTime());
        });
        calculateResult.forEach(x -> {
            times.add(x.get("time"));
        });

        List<String> stringList = times.stream().distinct().collect(Collectors.toList());
        stringList = stringList.stream().sorted().collect(Collectors.toList());
        return stringList;
    }

    @Override
    public CheckResult<Object> online(TelemetryDto telemetryDto) {
        List<DsTaskInfo> infoList = dsTaskInfoService.selectTList(DsTaskInfo.builder().satelliteCode(telemetryDto.getSatelliteCode()).name(telemetryDto.getName()).type(SystemModelTypeEnum.TREND_FORECASTING.getSystemModelTypeCode()).build());
        if (infoList.size() >= 1) {
            return CheckResult.fail("任务名称与任务列表中重复,请修改任务名称");
        }
        /*校验如果选择了处理后的数据需要判断时间和间隔
         * 1.检测开始时间不能早预处理时间
         * 2.轮询周期需要大于预处理周期
         */
        if(telemetryDto.getOriginalDataSources() == 1){
            String msg = checkCycleAndTime(telemetryDto);
            if(msg != null){
                return CheckResult.fail(msg);
            }
        }
        // 新增任务列表
        DsTaskInfo taskInfo = Convert.convert(DsTaskInfo.class, telemetryDto);
        taskInfo.setJsonParams(telemetryDto.getParamCode());
        taskInfo.setAlgorithmName(telemetryDto.getAlgorithmName());
        taskInfo.setParamCodeName(telemetryDto.getParamCodeName());
        taskInfo.setName(telemetryDto.getSatelliteCode() + "_" + DateUtil.format(telemetryDto.getStartTime(), "yyyyMMddHHmmss"));
        taskInfo.setEndTime(taskInfo.getStartTime());
        taskInfo.setStatus(1);
        taskInfo.setName(telemetryDto.getName());
        taskInfo.setCycle(telemetryDto.getCycle());
        taskInfo.setStep("10");
        // 记录任务类型
        taskInfo.setType(3);
        dsTaskInfoService.insertT(taskInfo);
        return CheckResult.success();
    }

    private String checkCycleAndTime(TelemetryDto telemetryDto) {
        /*构建任务查询条件*/
        Example example = new Example(DsTaskInfo.class);
        Example.Criteria criteria = example.createCriteria();
        example.orderBy("startTime").desc();
        criteria.andEqualTo("satelliteCode",telemetryDto.getSatelliteCode());
        criteria.andLike("params",telemetryDto.getParamCode());
        criteria.andLike("type","1");
        DsTaskInfo selectBody =  DsTaskInfo.builder()
                .satelliteCode(telemetryDto.getSatelliteCode())
                .jsonParams(telemetryDto.getParamCode())
                .type(1)
                .build();
        List<DsTaskInfo> taskInfos = dsTaskInfoService.selectByExample(selectBody);
        if(CollUtil.isNotEmpty(taskInfos)){
            DsTaskInfo taskInfo = taskInfos.get(0);
            /*如果事后诊断的开始时间在预处理之前，则给出提示*/
            if(telemetryDto.getStartTime().before(taskInfo.getStartTime())){
                return "开始时间不能早预处理时间【"+taskInfo.getStartTime()+"】";
            }
            /*如果周期小于预处理周期则给出提示*/
            /*趋势预测周期为分钟，需要数据处理的周期(小时)乘以60*/
            if(Integer.parseInt(taskInfo.getCycle())*60 > Integer.parseInt(telemetryDto.getCycle())){
                return "轮询周期不能小于预处理周期【"+taskInfo.getCycle()+"小时】";
            }
        }
        return null;
    }

    /**
     * 根据子任务id获取任务预测点集合
     *
     * @param predictDataVo 任务id
     * @return 结果日志
     */
    @Override
    public CheckResult<Object> getTaskTrendDataList(PredictDataVo predictDataVo) throws UnknownHostException {
        List<String> xAxi = new LinkedList<>();
        List<String> finxAxi = new ArrayList<>();
        HashMap<String, Object> map = new HashMap<>();
        List<TaskResultVo> changeMap =new ArrayList<>();
        List<DsTelemetryData> telemetryData =new ArrayList<>();
        List<DsTelemetryData> realTimetelemetryData =new ArrayList<>();
        TelemetryDto convert = Convert.convert(TelemetryDto.class, predictDataVo);
        Map<String, List<DsTelemetryData>> listMap = dsDiagnoseService.selectUsedTelemetryData(TableNameConstant.RUN_TASK_TELEMETRY + predictDataVo.getTaskId(), convert);
        /*之前查询的遥测*/
//        Map<String, List<TelemetryData>> listMap = diagnoseService.selectTelemetryData(convert);
        if (MapUtil.isNotEmpty(listMap)) {
            telemetryData = listMap.get(predictDataVo.getParamCode());
            if (CollUtil.isNotEmpty(telemetryData)) {
                try {
                    //telemetryData = addDataToListForTrend(telemetryData);
                    DateTime parseStartTime = DateUtil.parse(telemetryData.get(telemetryData.size() - 1).getTime(), "yyyy-MM-dd HH:mm:ss");
                    predictDataVo.setStartTime(parseStartTime);
                    //获取当前时间的趋势预测数据
                    DsTaskInfo taskInfo= dsTaskInfoService.selectTList(DsTaskInfo.builder().id(predictDataVo.getTaskId()).build()).get(0);
                    //添加告警门限
                    map.put("threshold",taskInfo.getThreshold());
                    DateTime trendEndTime =DateUtil.offsetSecond(parseStartTime,taskInfo.getTimeSpan()*taskInfo.getPredNumber());
                    predictDataVo.setTrendEndTime(trendEndTime);
                    List<TaskResultVo> taskTrendDataList = dsFaultInfoService.getTaskTrendDataList(predictDataVo);
                    realTimetelemetryData = dsFaultInfoService.getRealTimeDataList(predictDataVo);
                    //Long  interruptTime=Long.parseLong(taskInfo.getStep())*60*1000/2;
                    if (CollUtil.isNotEmpty(taskTrendDataList)) {
                        taskTrendDataList = taskTrendDataList.stream().distinct().collect(Collectors.toList());
                        taskTrendDataList.sort(Comparator.comparing(y -> DateUtil.parse(y.getTime(), "yyyy-MM-dd HH:mm:ss.SSS").getTime()));

                        //补全空缺值
                        //taskTrendDataList = addDataToList(taskTrendDataList);
                        taskTrendDataList.sort(Comparator.comparing(y -> DateUtil.parse(y.getTime(), "yyyy-MM-dd HH:mm:ss.SSS").getTime()));
                    }
                    telemetryData.stream().forEach(item -> xAxi.add(item.getTime()));
                    if (CollUtil.isNotEmpty(taskTrendDataList)) {
                        taskTrendDataList.stream().forEach(x -> xAxi.add(x.getTime()));
                    }

                    xAxi.sort(Comparator.comparing(x -> DateUtil.parse(x, "yyyy-MM-dd HH:mm:ss.SSS").getTime()));
                    finxAxi = xAxi.stream().distinct().collect(Collectors.toList());
                    changeMap = addNullValue(finxAxi, taskTrendDataList);
                    telemetryData=addNullValueToTelemetry(finxAxi,telemetryData);
                    realTimetelemetryData = addNullValueToTelemetry(finxAxi,realTimetelemetryData);
                } catch (Exception e) {
                    log.error("请检查遥测数据格式是否正确", e);
                    faultReportService.faultReport(ModuleEnum.SHZD.getCode(), ModuleEnum.SHZD.getMsg(),"测数据格式正确性","检查遥测数据格式是否正确");
                    throw new HealthException("请检查遥测数据格式是否正确");
                }

            }
            map.put("xAis", finxAxi);
            map.put("taskTrendDataList", changeMap);
            map.put("telemetryDataList", telemetryData);
            map.put("realTimeDataList", realTimetelemetryData);
            return CheckResult.success(map);
        }

        return CheckResult.success();

    }

    /**
     * 补充数据
     *
     * @param xAxis 横坐标
     * @param list  需要补充的数据
     * @return 补充后结果
     */
    public   static List<TaskResultVo> addNullValue(List<String> xAxis, List<TaskResultVo> list) {
        List<TaskResultVo> finalList = new ArrayList<>();
        if (null != list) {
            Map<Object, TaskResultVo> map = new HashMap<>();
            for (TaskResultVo vo : list) {
                map.put(vo.getTime(), vo);
            }
            for (String xa : xAxis) {
                if (map.containsKey(xa)) {
                    finalList.add(map.get(xa));
                } else {
                    TaskResultVo vo=new TaskResultVo();
                    vo.setTime(xa);
                    vo.setValue(null);
                    finalList.add(vo);
                }

            }

        }

        return finalList;
    }

    /**
     * 补充数据
     *
     * @param xAxis 横坐标
     * @param list  需要补充的数据
     * @return 补充后结果
     */
    public   static List<DsTelemetryData> addNullValueToTelemetry(List<String> xAxis, List<DsTelemetryData> list) {
        List<DsTelemetryData> finalList = new ArrayList<>();
        if (null != list) {
            Map<Object, DsTelemetryData> map = new HashMap<>();
            for (DsTelemetryData vo : list) {
                map.put(vo.getTime(), vo);
            }
            for (String xa : xAxis) {
                if (map.containsKey(xa)) {
                    finalList.add(map.get(xa));
                } else {
                    DsTelemetryData vo=new DsTelemetryData();
                    vo.setTime(xa);
                    vo.setValue(null);
                    finalList.add(vo);
                }

            }

        }

        return finalList;
    }


    /**
     * 查询结果数据
     * @param resultDataVo
     * @return 结果日志
     */
    @Override
    public CheckResult<Object> getResultDataList(ResultDataVo resultDataVo) throws UnknownHostException {
        List<CalculateData> dataList = selectResultData(resultDataVo);
        if (null != dataList && dataList.size()>0 )
            return CheckResult.success(dataList);
        else
            return CheckResult.fail("未查询到数据");
    }

    @Override
    /**
     * 获取结果数据
     * @param resultDataVo 查询条件
     * @return List<TelemetryData>
     */
    public List<CalculateData> selectResultData(ResultDataVo resultDataVo){
        SimpleDateFormat sdf = new SimpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
        String sql ="SELECT  *  from HEALTH.tb_calculate_data\n" +
                "   WHERE\n" +
                "   sate_code = " +
                "'"+resultDataVo.getSatelliteCode()+"'\n"+
                "   AND param_code = " +
                "'"+resultDataVo.getParamCode()+"'\n"+
                "   AND time >= " +
                "'"+sdf.format(resultDataVo.getStartTime())+"'\n"+
                "   AND time  <=  " +
                "'"+sdf.format(resultDataVo.getEndTime())+"'\n"+
                "   ORDER BY time ASC";
        return selectBySql(sql,CalculateData.class);
    }
}
